package net.Group;

import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.*;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.ID;
import net.jxta.id.IDFactory;
import net.jxta.impl.peergroup.StdPeerGroupParamAdv;
import net.jxta.impl.protocol.ModuleImplAdv;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.platform.ModuleSpecID;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.Group.AccessService.*;
import net.Group.MembershipService.*;

import java.awt.Component;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JOptionPane;

import jxta.security.signature.Signature;

import net.Group.MembershipService.*;

public class PrivatePeerGroup  {

    private PeerGroup  myNetPeerGroup=null, SecurePeerGroup=null;
    private final static PeerGroupID SecurePeerGroupID = PeerGroupID.create(URI.create("urn:jxta:uuid-87AD41D4CA104EE89B0DC68255E3B3E959616261646162614E5047205032503302"));
    public SecureCredential myCredential;
    public StructuredTextDocument stdCompatStatement = // ??? Taken from StdPeerGroup
        mkCS();
    public String peerGroupName = "";
    
    // The mime type of all documents used in this example
    public static final String DOCUMENT_MIME_TYPE="text";
    // The base type of all documents
    public static final String DOCUMENT_BASE_TYPE="xml";
    // This is the root element documents created
    public static final String DOCUMENT_ROOT_ELEMENT="Comp";    
    // Key ??? What is this used for ?
    private static final String KEY="Efmt";    
    // Value ??? What is this used for ?
    private static final String VALUE="JDK1.4";
    // Key used to represent the binding
    private static final String BINDING_KEY="Bind";
    // Value of the binding key.It represents the binding 
    // of JXTA that we use.
    private static final String BINDING_VALUE="V1.0 Ref Impl";
    public static QueryOut qout = null;
    public static QueryIn qin = null;
    public ModuleImplAdvertisement SecureMembershipModuleImplAdv;
    
    /** Creates new RootWS */
    public PrivatePeerGroup(PeerGroup parentGroup) {
        // Starts the JXTA Platform
        this.myNetPeerGroup = parentGroup;
        if (parentGroup!=null) {
            System.out.println("JXTA platform Started ...");
        } else {
            System.err.println("Failed to start JXTA : myNetPeerGroup is null");
            System.exit(1);
        }
    }

    //??? Taken from StdPeerGroup because it was private. This should have 
    //* been in a utility class.
   protected StructuredTextDocument mkCS() {
                                         
        StructuredTextDocument doc = (StructuredTextDocument)
           net.jxta.document.StructuredDocumentFactory.newStructuredDocument(
               new net.jxta.document.MimeMediaType(DOCUMENT_MIME_TYPE,
                                                   DOCUMENT_BASE_TYPE),
                                                   DOCUMENT_ROOT_ELEMENT);
        net.jxta.document.Element e = doc.createElement(KEY, VALUE);
        doc.appendChild(e);
        e = doc.createElement(BINDING_KEY, BINDING_VALUE);
        doc.appendChild(e);
        return doc;
   }
    
//    public PeerGroup joinPeerGroup(String login, String passwd) {
//        System.out.println("Hello");
//        // join the satellaPeerGroup
//        //if (satellaPeerGroup!=null) {
//            ///System.out.println(" Peer Group Created ...");
//            SecurePeerGroup=this.discoverPeerGroup(
//                            myNetPeerGroup,SecurePeerGroupID);
//            if (SecurePeerGroup!=null) {
//                System.out.println(" Peer Group Found ...");
//                this.joinPeerGroup(SecurePeerGroup,
//                                        login, passwd);
//                System.out.println("PeerGroupName: "+SecurePeerGroup.getPeerGroupName());
//            }
//            else {
//                System.out.println("Peer Group not found");
//            }
//        //}
//        //System.out.println(" Peer Group Joined ...");
//
//        return SecurePeerGroup;
//    }
    
    public boolean searchforLotPrivateGroup(){
    	System.out.println("Start Searching for LoT-Private Group");
        SecurePeerGroup=this.discoverPeerGroup(
                myNetPeerGroup,SecurePeerGroupID);
        if (SecurePeerGroup != null){
        	return true;
        }
        return false;
    }
    
//    public PeerGroup joinLotPrivateGroup(String login, String passwd){
//    	 
//    	if(this.joinPeerGroup(SecurePeerGroup,
//                 login, passwd))
//    	{
//    		JOptionPane.showMessageDialog((Component) null,
//					"Successful joining to the group", "Succeed!",
//					JOptionPane.INFORMATION_MESSAGE);
//    	}
//    	else{
//    		JOptionPane.showMessageDialog((Component) null,
//					"Fail to joining to the group", "Failed!",
//					JOptionPane.INFORMATION_MESSAGE);
//    	}
//    	 return SecurePeerGroup;
//    }

    public void createPeerGroup(PeerGroup rootPeerGroup,
                      String groupName) {
        // create the Peer Group by doing the following:
          // - Create a Peer Group Module Implementation Advertisement and publish it
          // - Create a Peer Group Adv and publish it
          // - Create a Peer Group from the Peer Group Adv and return this object
        //PeerGroup satellaPeerGroup=null;
        PeerGroupAdvertisement SecurePeerGroupAdvertisement;

        // Create the PeerGroup Module Implementation Adv
        ModuleImplAdvertisement SecureMembershipModuleImplAdv;
        SecureMembershipModuleImplAdv=this.createSecureMembershipPeerGroupModuleImplAdv(rootPeerGroup);
        
        //System.out.println("Secure Membership Module Impl Adv: "+SecureMembershipModuleImplAdv.toString());
        
        // Publish it in the parent peer group
        DiscoveryService rootPeerGroupDiscoveryService =
                                             rootPeerGroup.getDiscoveryService();
        try {
            rootPeerGroupDiscoveryService.publish(
                      SecureMembershipModuleImplAdv,
                      PeerGroup.DEFAULT_LIFETIME,
                      PeerGroup.DEFAULT_EXPIRATION);
            rootPeerGroupDiscoveryService.remotePublish(
                             SecureMembershipModuleImplAdv,
			     PeerGroup.DEFAULT_EXPIRATION);
        } catch (java.io.IOException e) {
            System.err.println("Can't Publish SecureMembershipModuleImplAdv");
            System.exit(1);
        }
        // Now, Create the Peer Group Advertisement
        SecurePeerGroupAdvertisement=
            this.createPeerGroupAdvertisement(SecureMembershipModuleImplAdv,
                                                           groupName);
        // Publish it in the parent peer group
        
        System.out.println("PGA :\n"+SecurePeerGroupAdvertisement.toString());
        
        try {
            rootPeerGroupDiscoveryService.publish(
                      SecurePeerGroupAdvertisement/*,
                      PeerGroup.DEFAULT_LIFETIME,
                      PeerGroup.DEFAULT_EXPIRATION*/);
            rootPeerGroupDiscoveryService.remotePublish(
                                  SecurePeerGroupAdvertisement/*, PeerGroup.DEFAULT_EXPIRATION*/);
        } catch (java.io.IOException e) {
            System.err.println("Can't Publish  SecurePeerGroupAdvertisement");
            System.exit(1);
        }
        // Finally Create the Peer Group
        if (SecurePeerGroupAdvertisement==null) {
            System.err.println("SecurePeerGroupAdvertisement is null");
        }
        try {
        	// do u need to create constant id group?
        	byte[] seed = "SEED".getBytes();
        	
        	PeerGroupID peerGroupID = IDFactory.newPeerGroupID( myNetPeerGroup.getPeerGroupID(),seed);
        	
            SecurePeerGroup=rootPeerGroup.newGroup(SecurePeerGroupAdvertisement.getPeerGroupID(),SecureMembershipModuleImplAdv,"Secure Peer Group","Implementation of LoT-RBAC system");
            
            SecurePeerGroup.init(rootPeerGroup, SecurePeerGroupID, SecureMembershipModuleImplAdv);
        	//SecurePeerGroup = rootPeerGroup.newGroup(SecurePeerGroupAdvertisement);
        	
            //System.out.println("Secure Peer group created \n PeerGroupID: "+peerGroupID.toString());
            
            //create the access service
        } catch (net.jxta.exception.PeerGroupException e) {
            System.err.println("Can't create Secure Peer Group from Advertisement");
            e.printStackTrace();
        }

    }


	private PeerGroupAdvertisement createPeerGroupAdvertisement(
         ModuleImplAdvertisement SecureMembershipModuleImplAdv,
         String groupName) {
        // Create a PeerGroupAdvertisement for the peer group
        PeerGroupAdvertisement  SecurePeerGroupAdvertisement=
                  (PeerGroupAdvertisement)
                  AdvertisementFactory.newAdvertisement(
                        PeerGroupAdvertisement.getAdvertisementType());

        // Instead of creating a new group ID each time, by using the
        //  line below
        // SecurePeerGroupAdvertisement.setPeerGroupID
        //               (IDFactory.newPeerGroupID());
        // I use a fixed ID so that each time I start PrivatePeerGroup,
        // it creates the same Group
        SecurePeerGroupAdvertisement.setPeerGroupID(
        		SecurePeerGroupID);
        SecurePeerGroupAdvertisement.setModuleSpecID(
                    SecureMembershipModuleImplAdv.getModuleSpecID());
        SecurePeerGroupAdvertisement.setName(groupName);
        SecurePeerGroupAdvertisement.setDescription("Peer Group using Secure Authentication");

        // Now create the Structured Document Containing the login and
        // passwd informations. Login and passwd are put into the Param
        // section of the peer Group
        
//        if (login!=null) {
            StructuredTextDocument parmtree =
                  (StructuredTextDocument)
                   StructuredDocumentFactory.newStructuredDocument(
                    new MimeMediaType("text/xml"),"Parm");
//            String loginAndPasswdString= login+":"+
//                        PasswdMembershipService.makePsswd(passwd)+":";
//            TextElement loginElement = parmtree.createElement(
//                                         "login",loginAndPasswdString);
//            
//            
            String creator = this.myNetPeerGroup.getPeerID().toString();
            TextElement e = parmtree.createElement("CreatorID",creator);
            
//            parmtree.appendChild(loginElement);
            parmtree.appendChild(e);
                        
            // All Right, now that loginAndPasswdElement
            // (The strucuted document
            // that is the Param Element for The PeerGroup Adv
            // is done, include it in the Peer Group Advertisement
            SecurePeerGroupAdvertisement.putServiceParam(PeerGroup.membershipClassID,parmtree);
//        }
        
        //now its time to create the access control list
        
        return SecurePeerGroupAdvertisement;
    }

    private ModuleImplAdvertisement createSecureMembershipPeerGroupModuleImplAdv(PeerGroup rootPeerGroup) {
        // Create a ModuleImpl Advertisement for the Passwd
        // Membership Service  Take a allPurposePeerGroupImplAdv
        //  ModuleImplAdvertisement parameter to
        // Clone some of its fields. It is easier than to recreate
        // everything from scratch

        // Try to locate where the PasswdMembership is within this
        // ModuleImplAdvertisement.
        // For a PeerGroup Module Impl, the list of the services
        // (including Membership) are located in the Param section
        ModuleImplAdvertisement allPurposePeerGroupImplAdv=null;
        try {
            allPurposePeerGroupImplAdv=rootPeerGroup.getAllPurposePeerGroupImplAdvertisement();
        } catch (java.lang.Exception e) {
            System.err.println("Can't Execute: getAllPurposePeerGroupImplAdvertisement();");
            System.exit(1);
        }
        ModuleImplAdvertisement SecureMembershipPeerGroupModuleImplAdv = allPurposePeerGroupImplAdv;
        ModuleImplAdvertisement SecureMembershipServiceModuleImplAdv = null;
        ModuleImplAdvertisement SecureAccessServiceModuleImplAdv = null;
        StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv = null;
        //passwdMembershipPeerGroupModuleImplAdv.setModuleSpecID(PeerGroup.refMembershipSpecID);
        try {
            passwdMembershipPeerGroupParamAdv =
                new StdPeerGroupParamAdv(
                    allPurposePeerGroupImplAdv.getParam());
        } catch (Exception e) {
            System.err.println("Can't execute: StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv =new StdPeerGroupParamAdv (allPurposePeerGroupImplAdv.getParam());");
            System.exit(1);
        }

        HashMap allPurposePeerGroupServicesHashtable = (HashMap)passwdMembershipPeerGroupParamAdv.getServices();
        Iterator allPurposePeerGroupServicesEnumeration = allPurposePeerGroupServicesHashtable.values().iterator();
        boolean membershipServiceFound=false;
        boolean accessServiceFound=false;
        while ((!membershipServiceFound) && (allPurposePeerGroupServicesEnumeration.hasNext())) {
            ModuleImplAdv allPurposePeerGroupServiceID = (ModuleImplAdv)allPurposePeerGroupServicesEnumeration.next();
            if (allPurposePeerGroupServiceID.getModuleSpecID().equals(PeerGroup.refMembershipSpecID)) {
                // allPurposePeerGroupMemershipServiceModuleImplAdv is
                // the all Purpose Mermbership Service for the all
                // purpose Peer Group  Module Impl adv
                ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv= (ModuleImplAdvertisement) allPurposePeerGroupServicesHashtable.get(PeerGroup.membershipClassID);
                //Create the passwdMembershipServiceModuleImplAdv
                SecureMembershipServiceModuleImplAdv=this.createSecureMembershipServiceModuleImplAdv(allPurposePeerGroupMemershipServiceModuleImplAdv);
                
                //Remove the All purpose Membership Service implementation
                allPurposePeerGroupServicesHashtable.remove(allPurposePeerGroupServiceID.getModuleSpecID());
                // And Replace it by the Secure Membership Service
                // Implementation
        allPurposePeerGroupServicesHashtable.put(
                           PeerGroup.membershipClassID,
                           SecureMembershipServiceModuleImplAdv);
                membershipServiceFound=true;
                
                
            } //end if (allPurposePeerGroupServiceID.
              // equals(PeerGroup.membershipClassID))
            
            if (allPurposePeerGroupServiceID.getModuleSpecID().equals(PeerGroup.refAccessSpecID)) {
            	
            	ModuleImplAdvertisement allPurposePeerGroupAccessServiceModuleImplAdv = (ModuleImplAdvertisement) allPurposePeerGroupServicesHashtable.get(PeerGroup.accessClassID);
            	//SecureAccessServiceModuleImplAdv = this.createSecureMembershipServiceModuleImplAdv(allPurposePeerGroupAccessServiceModuleImplAdv);
            	
            	// create Secure Access Service Module Implementation Adverstisement
            	SecureAccessServiceModuleImplAdv = (ModuleImplAdvertisement) AdvertisementFactory.newAdvertisement(ModuleImplAdvertisement.getAdvertisementType());
            	SecureAccessServiceModuleImplAdv.setModuleSpecID(LoTAccessService.loTAccessSpecID);
            	SecureAccessServiceModuleImplAdv.setCode("net.Group.AccessService.LoTAccessService");
            	SecureAccessServiceModuleImplAdv.setDescription("Module Impl Adverstisement for the LoT Access Service");
            	SecureAccessServiceModuleImplAdv.setCompat(allPurposePeerGroupAccessServiceModuleImplAdv.getCompat());
            	SecureAccessServiceModuleImplAdv.setUri(allPurposePeerGroupAccessServiceModuleImplAdv.getUri());
            	SecureAccessServiceModuleImplAdv.setProvider(allPurposePeerGroupAccessServiceModuleImplAdv.getProvider());
            	
            	 //Remove the All purpose Access Service Service implementation
                allPurposePeerGroupServicesHashtable.remove(allPurposePeerGroupServiceID.getModuleSpecID());
                // And Replace it by the Secure Membership Service
                // Implementation
                
                allPurposePeerGroupServicesHashtable.put(PeerGroup.accessClassID,SecureAccessServiceModuleImplAdv);
        
                accessServiceFound = true;
            	
            }
        }//end While
         // Now the Service Advertisements are complete. Let's
            // update the passwdMembershipPeerGroupModuleImplAdv by
            // Updating its param
           
            if(membershipServiceFound&&accessServiceFound){
            	
            SecureMembershipPeerGroupModuleImplAdv.setParam(
                     (Element) passwdMembershipPeerGroupParamAdv.getDocument(MimeMediaType.XMLUTF8));
            // Update its Spec ID This comes from the
            // Instant P2P PeerGroupManager Code (Thanks !!!!)
            if (!SecureMembershipPeerGroupModuleImplAdv.getModuleSpecID().equals(
                                    PeerGroup.allPurposePeerGroupSpecID)) {
                SecureMembershipPeerGroupModuleImplAdv.setModuleSpecID(IDFactory.newModuleSpecID(
                            SecureMembershipPeerGroupModuleImplAdv.getModuleSpecID().getBaseClass()));
            } else {
                ID passwdGrpModSpecID= ID.create(URI.create("urn:" + "jxta:uuid-"+ "DeadBeefDeafBabaFeedBabe000000010406"));

                SecureMembershipPeerGroupModuleImplAdv.
                 setModuleSpecID((ModuleSpecID) passwdGrpModSpecID);
          } //End Else
            
            System.out.println("Secure Membership PeerGroup ModuleImplAdv ModuleSpecuID:"+SecureMembershipPeerGroupModuleImplAdv.getModuleSpecID().toString());
            }


        return SecureMembershipPeerGroupModuleImplAdv;
    }


    private  ModuleImplAdvertisement createSecureMembershipServiceModuleImplAdv(ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv) {
        //Create a new ModuleImplAdvertisement for the
        // Membership Service
        ModuleImplAdvertisement SecureMembershipServiceModuleImplAdv = (ModuleImplAdvertisement) AdvertisementFactory.newAdvertisement(ModuleImplAdvertisement.getAdvertisementType());
        SecureMembershipServiceModuleImplAdv.setModuleSpecID(SecureMembershipService.SecureMembershipSpecID);
        SecureMembershipServiceModuleImplAdv.setCode("net.Group.MembershipService.SecureMembershipService");
        SecureMembershipServiceModuleImplAdv.setDescription("Module Impl Advertisement for the Secure Membership Service");
        SecureMembershipServiceModuleImplAdv.setCompat(allPurposePeerGroupMemershipServiceModuleImplAdv.getCompat());
        SecureMembershipServiceModuleImplAdv.setUri(allPurposePeerGroupMemershipServiceModuleImplAdv.getUri());
        SecureMembershipServiceModuleImplAdv.setProvider(allPurposePeerGroupMemershipServiceModuleImplAdv.getProvider());
        return SecureMembershipServiceModuleImplAdv;
    }

    private PeerGroup discoverPeerGroup(PeerGroup myNetPeerGroup,
                                    PeerGroupID satellaPeerGroupID) {
        // First discover the peer group
        // In most cases we should use discovery listeners so that
        // we can do the discovery asynchroneously.
        // Here I won't, for increased simplicity and because
        // The Peer Group Advertisement is in the local cache for sure
        PeerGroup SecurePeerGroup;
    DiscoveryService myNetPeerGroupDiscoveryService=null;
        if (myNetPeerGroup!=null) {
            myNetPeerGroupDiscoveryService =
                       myNetPeerGroup.getDiscoveryService();
        } else {
            System.err.println("Can't join  Peer Group since it's parent is null");
            System.exit(1);
        }
        boolean isGroupFound=false;
        Enumeration localPeerGroupAdvertisementEnumeration = null;
        PeerGroupAdvertisement SecurePeerGroupAdvertisement = null;
        while(!isGroupFound) {
            try {
                localPeerGroupAdvertisementEnumeration =
                    myNetPeerGroupDiscoveryService.
                    getLocalAdvertisements(DiscoveryService.GROUP, "GID", satellaPeerGroupID.toString());
            } catch (java.io.IOException e) {
                System.out.println("Can't Discover Local Adv");
            }
            if (localPeerGroupAdvertisementEnumeration!=null) {
                while (localPeerGroupAdvertisementEnumeration.
                                           hasMoreElements()) {
                    PeerGroupAdvertisement pgAdv=null;
                    pgAdv= (PeerGroupAdvertisement)
                         localPeerGroupAdvertisementEnumeration.
                                nextElement();
                    if (pgAdv.getPeerGroupID().equals(satellaPeerGroupID)) {
                        SecurePeerGroupAdvertisement=pgAdv;
                        isGroupFound=true ;
                        break ;
                    }
                }
            }
            try {
                Thread.sleep(5 * 1000);
            } catch(Exception e) {}
        }
        try {
        	 SecurePeerGroup=myNetPeerGroup.newGroup(SecurePeerGroupAdvertisement.getPeerGroupID(),SecureMembershipModuleImplAdv,"Secure Peer Group","Implementation of LoT-RBAC system");
        	//SecurePeerGroup=myNetPeerGroup.newGroup(SecurePeerGroupAdvertisement);
        } catch (net.jxta.exception.PeerGroupException e) {
            System.err.println("Can't create Peer Group from Advertisement");
            e.printStackTrace();
            return null;
        }
        return SecurePeerGroup;
    }

    public boolean joinSecureGroup(PeerGroup securePeerGroup, PeerGroup parent){
    	StructuredDocument document = null;
    	boolean verified = false;
        try{
            
            // The EncryptedDocumentsFactory is used to create an Encrypted Document.
            // RC4 symmetric encryption is used by the factory.
            // The document is supplied as credential to the group manager.The Group Manager
            // inturn uses this credentials document in the join process
            document = EncryptedDocumentsFactory.getEncryptedDocument();
            GroupManager manager = new GroupManager(myNetPeerGroup,parent);
            // A successful membership to the group returns a signed SecureCredential
            SecureCredential credential =(SecureCredential)manager.joinGroup(securePeerGroup,document,"Apply");
            // The SecureCredential is signed using RSA algorithm.
            // Now we will verify that the credential is indeed signed by the Membership Service
            byte[] messageBytes = credential.getMessageBytes();
            byte[] signatureArray =credential.getMessageSignatureBytes();
            // In order to verify we need a signature object.
            // For our convienence we take the Signature Object available in the
            // credential to verify
            Signature signature = credential.getSignature();
            // Initialize the signature to mode VERIFY.
            signature.init(Signature.MODE_VERIFY);
            // The actual verification
            verified = signature.verify(messageBytes, 0, messageBytes.length,
            signatureArray, 0, signatureArray.length);
            
            if( verified ){
            	myCredential = credential;
            }
            
            System.out.println("SecureCredential Verified !!");
            
        	}catch(Exception e){e.printStackTrace();}
        
//        } catch (jxta.security.exceptions.CryptoException cryptoException) 	{
//            LOG.error("Exception Occured",cryptoException);
//            System.exit(1);
//        } catch (com.lot.jxta.group.GroupManagerAuthenticationException managerExcp){
//            LOG.error("Exception Occured",managerExcp);
//            System.exit(1);
//        } catch (net.jxta.exception.ProtocolNotSupportedException managerExcp){
//            LOG.error("Exception Occured",managerExcp);
//            System.exit(1);
//        }catch (Exception exception){
//            LOG.error("Exception Occured",exception);
//            System.exit(1);
        	
        	return verified;
        }
    
    
//    private boolean joinPeerGroup(PeerGroup SecurePeerGroup, String login,String passwd) {
//        // Get the Heavy Weight Paper for the resume
//        // Alias define the type of credential to be provided
//        StructuredDocument creds = null;
//        try {
//            // Create the resume to apply for the Job
//            // Alias generate the credentials for the Peer Group
//            AuthenticationCredential authCred = new AuthenticationCredential(SecurePeerGroup, null, creds);
//
//            // Create the resume to apply for the Job
//            // Alias generate the credentials for the Peer Group
//            MembershipService membershipService =  SecurePeerGroup.getMembershipService();
//
//            // Send the resume and get the  Job application form
//        // Alias get the Authenticator from the Authentication creds
//            Authenticator auth = membershipService.apply(authCred);
//
//            // Fill in the Job Application Form
//            // Alias complete the authentication
//            completeAuth( auth, login, passwd );
//
//            // Check if I got the Job
//            // Alias Check if the authentication that was submitted was
//            //accepted.
//            if (!auth.isReadyForJoin()) {
//                System.out.println( "Failure in authentication.");
//                System.out.println( "Group was not joined. Does not know how to complete authenticator");
//                return false;
//            }
//            // I got the Job, Join the company
//            // Alias I the authentication I completed was accepted,
//            // therefore join the Peer Group accepted.
//            
//            
//            //myCredential = membershipService.join(auth);
//            return true;
//        } catch (Exception e) {
//            System.out.println("Failure in authentication.");
//            System.out.println("Group was not joined. Login was incorrect.");
//            e.printStackTrace();
//        }
//        return false;
//    }

//    private  void completeAuth(Authenticator auth, String login,
//                                   String passwd) throws Exception {
//
//        Method [] methods = auth.getClass().getMethods();
//        Vector authMethods = new Vector();
//
//        // Find out with fields of the application needs to be filled
//        // Alias Go through the methods of the Authenticator class and
//        // copy them sorted by name into a vector.
//        for(int eachMethod = 0;
//               eachMethod < methods.length; eachMethod++) {
//            if (methods[eachMethod].getName().startsWith("setAuth") ) {
//                if (Modifier.isPublic(
//                      methods[eachMethod].getModifiers())) {
//                    // sorted insertion.
//                    for(int doInsert = 0; doInsert<= authMethods.size(); doInsert++) {
//                        int insertHere = -1;
//                        if(doInsert == authMethods.size())
//                            insertHere = doInsert;
//                        else {
//                            if (methods[eachMethod].getName().compareTo(((Method)authMethods.elementAt(
//                                     doInsert)).getName()) <= 0 )
//                                insertHere = doInsert;
//                        } // end else
//
//                        if (-1!= insertHere) {
//                            authMethods.insertElementAt(
//                                methods[eachMethod],insertHere);
//                            break;
//                        } // end if ( -1 != insertHere)
//                    } // end for (int doInsert=0
//                } // end if (modifier.isPublic
//            } // end if (methods[eachMethod]
//        } // end for (int eachMethod)
//Object [] AuthId = {login};
//        Object [] AuthPasswd = {passwd};
//
//        for (int eachAuthMethod = 0; eachAuthMethod<authMethods.size(); eachAuthMethod++ ) {
//            Method doingMethod = (Method) authMethods.elementAt(eachAuthMethod);
//            String authStepName = doingMethod.getName().substring(7);
//            if (doingMethod.getName().equals("setAuth1Identity")) {
//                // Found identity Method, providing identity
//                doingMethod.invoke(auth, AuthId);
//
//            } else
//                if (doingMethod.getName().equals("setAuth2_Password")) {
//                    // Found Passwd Method, providing passwd
//                    doingMethod.invoke(auth, AuthPasswd);
//                }
//        }
//    }
//
//   private void printXmlAdvertisement(String title, Advertisement adv){
//        // First, Let's print a "nice" Title
//        String separator = "";
//        for (int i=0 ; i<title.length()+4; i++) {
//            separator=separator+"-";
//        }
//        System.out.println(separator);
//        System.out.println("| " + title  +" |");
//        System.out.println(separator);
//
//        // Now let's print the Advertisement
//        System.out.println(adv.toString());
//
//        // Let's end up with a line
//        System.out.println(separator);
//    }

   public PeerGroup getPeerGroup(){
	   return SecurePeerGroup;
   }
   
   public String getPeerGroupName(){
	   return SecurePeerGroup.getPeerGroupName();
   }
   
   public Credential getFinalCredential(){
	   if(myCredential != null)
	   return myCredential;
	   else return null;
   }
    public static void main(String args[]) throws Throwable {
    	PeerGroup myNetPeerGroup = null;
    	try{
    		myNetPeerGroup = PeerGroupFactory.newNetPeerGroup();
    	}catch(PeerGroupException e){
    		System.out.println("Fatal error: group creation failure");
    		e.printStackTrace();
    		System.exit(1);
    	}
    	
    	
    	
        PrivatePeerGroup lotgroup = new PrivatePeerGroup(myNetPeerGroup);
        //search first 
        
        if (lotgroup.searchforLotPrivateGroup()){
        	if(lotgroup.joinSecureGroup(lotgroup.getPeerGroup(), myNetPeerGroup))
        		System.out.println("Found LotGroup and successful join it!");
        	
        }
        else{
        System.out.println("LotGroup not founded! Creating LoTGroup!");
        lotgroup.createPeerGroup(myNetPeerGroup, "Test");
        lotgroup.joinSecureGroup(lotgroup.getPeerGroup(), myNetPeerGroup);
        
      }
        
        
        System.out.println("[===== Secure Group Details =====]");
        StructuredTextDocument doc = (StructuredTextDocument)lotgroup.myCredential.getDocument(new MimeMediaType("text/plain"));
        StringWriter out = new StringWriter();
        doc.sendToWriter(out);
        System.out.println(out.toString());
        //System.exit(0);
        
        qout = new QueryOut(lotgroup.getPeerGroup(),"P1",lotgroup.myCredential);
        qin = new QueryIn(lotgroup.getPeerGroup(),qout);
        qout.startingPipe();
        qin.startListening();
        
    }
}
